// 实现这个项目的构建任务

const { src, dest, parallel, series, watch } = require('gulp')

const del = require('del')
const browerSync = require('browser-sync')
const minimist = require('minimist')

const loadPlugins = require('gulp-load-plugins')

const plugins = loadPlugins()
const sass = plugins.sass(require('sass'))
const { babel, swig, imagemin } = plugins;

const bs = browerSync.create();

var options = minimist(process.argv.slice(2));

const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'About',
      link: 'about.html'
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}

const clean = () => {
  return del(['dist', 'temp', '.publish'])
}

// style任务：scss 转 css
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })
    .pipe(sass())
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

// script任务: ES6 转 JS 
const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

// page任务: 填充数据到html文件并输出到temp文件夹
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(
      swig({
        data,
        defaults: { cache: false },
      })
    )
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const serve = () => {
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/styles/*.js', script)
  watch('src/**/*.html', page)
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload)

  bs.init({
    notify: options.open || false,
    port: options.port || 2080,
    server: {
      baseDir: ['temp', 'src', 'public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const serveProd = () => {
  watch('dist', bs.reload)

  bs.init({
    notify: options.open || false,
    port: options.port || 2080,
    server: {
      baseDir: ['dist']
    }
  })
}

const userefMini = () => {
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: [ 'temp', '.'] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true,
    })))
    .pipe(dest('dist'))
}

const useref = () => {
  // production build 时minify资源文件
  if (options.production || options.prod) {
    return userefMini()
  }
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: [ 'temp', '.'] }))
    .pipe(dest('dist'))
}
// dist文件夹所有内容推送到git
const pushGhPage = () => {
  return src('**/*', { base: 'dist' })
    .pipe(plugins.ghPages({
      remoteUrl: 'https://gitee.com/aruna/lagou-e-task.git'
    }));
}
// 样式检查
const lintScript = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
      .pipe(plugins.eslint({
        rules: {
          'no-alert': 0,
          'no-bitwise': 0,
          'camelcase': 1,
          'curly': 1,
          'eqeqeq': 0,
          'no-eq-null': 0,
          'guard-for-in': 1,
          'no-empty': 1,
          'no-use-before-define': 0,
          'no-obj-calls': 2,
          'no-unused-vars': 0,
          'new-cap': 1,
          'no-shadow': 0,
          'strict': 1,
          'no-invalid-regexp': 1,
          'comma-dangle': 1,
          'no-undef': 1,
          'no-new': 1,
          'no-extra-semi': 1,
          'no-debugger': 1,
          'no-caller': 1,
          'semi': 1,
          'quotes': 0,
          'no-unreachable': 1
        },
        envs: ['browser', 'es6']
      }))
      .pipe(plugins.eslint.format())
      .pipe(plugins.eslint.failAfterError());
}
// 脚本检查
const lintStyle = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })
      .pipe(plugins.sassLint())
      .pipe(plugins.sassLint.format())
      .pipe(plugins.sassLint.failOnError())
}
const lint = parallel(lintScript, lintStyle)

const compile = parallel(style, script, page)

const build = series(
  clean,
  parallel(
    series(compile, useref),
    image,
    font,
    extra
  )
)

const productionBuild = series(
  clean,
  parallel(
    series(compile, userefMini),
    image,
    font,
    extra
  )
)

const start = series(productionBuild, serveProd)

const deploy = series(build, pushGhPage)

module.exports = {
  clean,    // Clean the `dist` & `temp` files.
  lint,     // Lint the styles & scripts files.
  compile,  // Compile the styles & scripts & pages file.
  build,    // Builds the app for production to the `dist` folder.
  start,    // Running projects in production mode.
  serve,    // Runs the app in development mode with a automated server.
  deploy,   // Deploy the `dist` folder to GitHub Pages
}
